//
// Created by chizuru on 2025/9/16.
//

#include "ProtocolCodecFactory.h"
#include "CLBProtocolCodec.h"
#include "ModBusProtocolCodec.h"

#define REGISTER_CODEC(NAME, CODEC_TYPE) \
    static inline ProtocolCodecFactory::Registrar _reg_##CODEC_TYPE { NAME, [](){ return std::make_unique<CODEC_TYPE>(); } }

REGISTER_CODEC("camera_link_default", CLBProtocolCodec);
REGISTER_CODEC("modbus_default", ModBusProtocolCodec);
ProtocolCodecFactory& ProtocolCodecFactory::instance() {
    static ProtocolCodecFactory f;
    return f;
}

void ProtocolCodecFactory::registerFactory(std::string name, CodecFactoryFn fn) {
    std::scoped_lock lk(mutex);
    factories[std::move(name)] = std::move(fn);
}

std::unique_ptr<IProtocolCodec> ProtocolCodecFactory::create(const std::string& name) const {
    std::scoped_lock lk(mutex);
    auto it = factories.find(name);
    if (it == factories.end())
        return nullptr;
    return it->second();
}